package com.hxzy.shop.controller;

import cn.hutool.core.util.ObjectUtil;
import com.hxzy.shop.cachedao.AuthCacheService;
import com.hxzy.shop.config.oauth.Oauth2TokenDto;
import com.hxzy.shop.constant.AuthConstant;
import com.hxzy.shop.constant.RedisConstant;
import com.hxzy.shop.dto.auth.resp.LoadUserResp;
import com.hxzy.shop.entity.Merchant;
import com.hxzy.shop.mapper.MerchantMapper;
import com.hxzy.shop.utils.WebUtil;
import com.hxzy.shop.vo.ApiException;
import com.hxzy.shop.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Date;
import java.util.Map;


@RestController
@Api(tags = "认证中心登录认证")
@RequestMapping("/oauth")
public class AuthController {

    /**
     * redis缓存操作（图片验证码和登录令牌操作）
     */
    @Resource
    private AuthCacheService redisService;

    /**
     * 通过 oauth/token 来获取 token,系统自带的类
     */
    @Resource
    private TokenEndpoint tokenEndpoint;

    /**
     * 商户表
     */
    @Resource
    private MerchantMapper merchantMapper;


    /**
     * OAuth授权模式4种：grant_type=code 授权码， grant_type=password密码式 , grant_type=client_credentials 凭证式
     *                  response_type=token  隐藏式
     *   HashMap<String,String> parameters =new HashMap<>();
     *         parameters.put("grant_type","password");
     *         parameters.put("client_id", AuthConstant.ADMIN_CLIENT_ID);
     *         parameters.put("client_secret",AuthConstant.ADMIN_CLIENT_SECRET);
     *         parameters.put("username",req.getAccount());
     *         parameters.put("password",req.getPassword());
     * @param principal
     * @param parameters
     * @return
     * @throws HttpRequestMethodNotSupportedException
     */
    @ApiOperation("Oauth2获取token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "grant_type", value = "授权模式", example = "password",required = true),
            @ApiImplicitParam(name = "client_id", value = "Oauth2客户端ID", required = true),
            @ApiImplicitParam(name = "client_secret", value = "Oauth2客户端秘钥", required = true),
            @ApiImplicitParam(name = "username", value = "登录用户名", required = true),
            @ApiImplicitParam(name = "password", value = "登录密码", required = true),
    })
    @PostMapping(value = "/token")
    public Result<Oauth2TokenDto> postAccessToken(@ApiIgnore Principal principal, @ApiIgnore @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        // 如果发请的请求  client_id=Admin  或者   client_id=Admin_Slave ，请求头中就必须要另一个参数  merchant_id=商户ID
        HttpServletRequest request = WebUtil.getRequest();
        String merchantId=null;
        //获取请求头中的商户id
        if (ObjectUtil.isNotEmpty(request)){
            merchantId=  request.getHeader(AuthConstant.MERCHANT_ID);
        }

        // 调用oauth认证服务
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();

        System.out.println(oAuth2AccessToken.toString());
        assert oAuth2AccessToken != null;
        //返回结果
        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()
                .token(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn())
                .tokenHead(AuthConstant.JWT_TOKEN_PREFIX).build();

        String redisKey=null;
        //判断是否是商户，并且存储到redis中
        if (ObjectUtil.isNotEmpty(merchantId)){
            //查询商户信息
            Merchant merchant = merchantMapper.selectById(merchantId);
            System.out.println("-------");
            System.out.println(merchant);
            //判断是否过期
            if (ObjectUtil.isNotEmpty(merchant.getDisableTime())&&merchant.getDisableTime().before(new Date())){
                throw new ApiException(500,"当前商户已经过期，请续费后使用");
            }
            if (merchant.getDisable()){
                throw new ApiException(500,"当前商户已经过期，请续费后使用");
            }

            //构造  authorization: client_id=[Admin后台管理, Admin_Slave 后台分店管理, back_admin 总端后台]
            redisKey = RedisConstant.AUTHORIZATION + parameters.get("client_id") + ":" + parameters.get("username")+merchantId;
        }else {
             redisKey = RedisConstant.AUTHORIZATION + parameters.get("client_id") + ":" + parameters.get("username");
        }
        redisService.saveToken(redisKey, oAuth2AccessToken.getValue(), oAuth2AccessToken.getExpiresIn());
        return Result.success(oauth2TokenDto);
    }




}
